﻿using System;
using System.Collections.Generic;
using System.Linq;
using Infrastructure.ElasticSearch.Enums;

namespace Infrastructure.ElasticSearch.Models
{
    public class EsMultiSearchModel
    {
        public EsMultiSearchModel()
        {
            HasValue = false;
            Operator = QueryOperator.Include;
        }

        public EsMultiSearchModel(List<string> values, QueryOperator opt = QueryOperator.Equal, List<string> allValues = null)
        {
            SetValues(values);
            SetQueryOperator(opt);
            if (allValues != null)
            {
                SetNoMatchValues(allValues);
            }
        }


        public bool HasValue { get; private set; } = false;
        public QueryOperator Operator { get; private set; }
        public List<string> Values { get; private set; }

        public List<string> MustNotMatchValues { get; private set; }

        public void SetNoMatchValues(List<string> allValues)
        {
            if (!allValues.Any())
            {
                return;
            }

            if (Operator != QueryOperator.Only)
            {
                return;
            }

            MustNotMatchValues = allValues.Except(Values).ToList();

            if (MustNotMatchValues.All(x => x.IsNullOrWhiteSpace()))
            {
                Operator = QueryOperator.Include;
            }
        }

        public void SetValues(List<string> values)
        {
            if (values.IsNullOrEmpty())
            {
                Values = null;
                HasValue = false;
                return;
            }

            if (values.Any(x => !x.IsNullOrWhiteSpace()))
            {
                Values = values;
                HasValue = true;
            }
        }

        public void SetQueryOperator(QueryOperator opt)
        {
            Operator = opt;
        }

        public void ClearValues()
        {
            Values = null;
            HasValue = false;
        }

        public bool Contains(string val)
        {
            if (Values.IsNullOrEmpty()) return false;

            return Values.Any(v => v == val);
        }

        public bool ContainsAny(params string[] vals)
        {
            if (Values.IsNullOrEmpty() || vals.IsNullOrEmpty()) return false;

            return Values.Any(v => vals.Contains(v));
        }
    }

    public static class EsMultiSearchModelExtentions
    {
        public static bool HasValue(this EsMultiSearchModel model)
        {
            return model != null && model.HasValue;
        }
    }
}